package com.thread.xxstudy;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 *   ReentrantLok的newCondition方法  可以指定同一把锁的不同线程被唤醒（signal） 等待（await）
 */
public class LockCondition {

    static class Buff {
        final Lock rlock = new ReentrantLock();
        Condition c1 = rlock.newCondition();//put
        Condition c2 = rlock.newCondition();//take

        Object[] o = new Object[5];
        int count ,putptr ,takeptr;


        public void put(Object xx) {
             System.out.println(Thread.currentThread().getName()+"put等待锁");
            rlock.lock();
            System.out.println(Thread.currentThread().getName()+"put得到锁");
            try {
                while (count == o.length) {
                    System.out.println(Thread.currentThread().getName()+"put陷入等待");
                    c1.await();
                }
                o[putptr] = xx;
                if (++putptr == o.length) {
                   putptr = 0;
                }
                ++count;
                System.out.println(Thread.currentThread().getName() + "通知take任务");
                c2.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                rlock.unlock();
                System.out.println(Thread.currentThread().getName() + "put释放锁");
            }
        }

        public  Object take() throws InterruptedException {
            System.out.println(Thread.currentThread().getName()+"take等待锁");
            rlock.lock();
            System.out.println(Thread.currentThread().getName()+"take得到锁");
            try {
                if (count == 0) {
                    System.out.println(Thread.currentThread().getName()+"take陷入等待");
                    c2.await();
                }
                Object xx = o[takeptr];
                if (++takeptr == o.length) {
                     takeptr = 0;
                }
                --count;
                c1.signal();
                System.out.println(Thread.currentThread().getName() + "通知get任务");
                return xx;
            }finally {
                rlock.unlock();
                System.out.println(Thread.currentThread().getName() + "take释放锁");
            }
        }

     /*   public static void main(String[] args) {

            Buff buff = new Buff();
            Thread c1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i=0;i<10;i++) {
                        try {
                            Object take = buff.take();
                          // System.out.println("take---" + take);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });

            Thread c2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 10; i++) {
                        buff.put("xx-" + i);
                    }
                }
            });

            c1.start();
            c2.start();
        }*/
    }
}
